'use client';

import React, { useEffect, useState, useMemo } from 'react';
import { Card } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Button } from '@/components/ui/button';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { 
  PlusCircle, 
  MinusCircle, 
  ArrowLeftRight, 
  CheckCircle2, 
  AlertCircle 
} from 'lucide-react';

// 导入差异比较库
// 注意：实际项目中需要安装 diff-match-patch 库
// yarn add diff-match-patch
// yarn add -D @types/diff-match-patch
// 这里使用临时的类型定义
interface DiffMatchPatch {
  diff_main: (text1: string, text2: string) => Array<[number, string]>;
  diff_prettyHtml: (diffs: Array<[number, string]>) => string;
}

declare global {
  interface Window {
    diff_match_patch: new () => DiffMatchPatch;
  }
}

// 差异类型
type DiffType = -1 | 0 | 1; // -1: 删除, 0: 相等, 1: 添加

// 差异项
interface DiffItem {
  type: DiffType;
  text: string;
}

interface DiffViewerProps {
  sourceContent: any;
  targetContent: any;
  sourceTitle?: string;
  targetTitle?: string;
  onMerge?: (mergedContent: any) => void;
  onSelectSource?: () => void;
  onSelectTarget?: () => void;
  className?: string;
}

export function DiffViewer({
  sourceContent,
  targetContent,
  sourceTitle = '源文档',
  targetTitle = '目标文档',
  onMerge,
  onSelectSource,
  onSelectTarget,
  className = ''
}: DiffViewerProps) {
  const [activeTab, setActiveTab] = useState<string>('split');
  const [diffs, setDiffs] = useState<DiffItem[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  
  // 判断内容是否有差异
  const hasDifferences = useMemo(() => {
    return diffs.some(diff => diff.type !== 0);
  }, [diffs]);
  
  // 内容相似度百分比
  const similarityPercentage = useMemo(() => {
    if (diffs.length === 0) return 100;
    
    const equalChars = diffs
      .filter(diff => diff.type === 0)
      .reduce((sum, diff) => sum + diff.text.length, 0);
    
    const totalChars = diffs.reduce((sum, diff) => sum + diff.text.length, 0);
    
    return Math.round((equalChars / totalChars) * 100);
  }, [diffs]);
  
  // 初始化差异比较
  useEffect(() => {
    const computeDiff = async () => {
      setIsLoading(true);
      
      try {
        // 转换内容为字符串
        const sourceText = typeof sourceContent === 'string' 
          ? sourceContent 
          : JSON.stringify(sourceContent, null, 2);
        
        const targetText = typeof targetContent === 'string' 
          ? targetContent 
          : JSON.stringify(targetContent, null, 2);
        
        // 使用diff-match-patch进行差异比较
        // 如果浏览器环境中没有，则动态加载
        let diffMatchPatch: DiffMatchPatch;
        
        if (typeof window !== 'undefined') {
          if (window.diff_match_patch) {
            diffMatchPatch = new window.diff_match_patch();
          } else {
            // 这里简单实现一个差异比较函数
            // 在实际项目中应该使用完整的diff-match-patch库
            const simpleDiff = (text1: string, text2: string): Array<[DiffType, string]> => {
              if (text1 === text2) return [[0, text1]];
              return [[-1, text1], [1, text2]];
            };
            
            diffMatchPatch = {
              diff_main: simpleDiff,
              diff_prettyHtml: () => ''
            };
          }
          
          const diffResult = diffMatchPatch.diff_main(sourceText, targetText);
          
          // 转换差异结果为我们的格式
          const formattedDiffs: DiffItem[] = diffResult.map(([type, text]) => ({
            type: type as DiffType,
            text
          }));
          
          setDiffs(formattedDiffs);
        }
      } catch (error) {
        console.error('计算差异失败:', error);
        // 出错时使用简单的差异
        setDiffs([
          { type: -1, text: JSON.stringify(sourceContent, null, 2) },
          { type: 1, text: JSON.stringify(targetContent, null, 2) }
        ]);
      } finally {
        setIsLoading(false);
      }
    };
    
    computeDiff();
  }, [sourceContent, targetContent]);
  
  // 渲染差异项
  const renderDiffItem = (diff: DiffItem) => {
    switch (diff.type) {
      case -1: // 删除
        return (
          <span className="bg-red-100 text-red-800 px-1 rounded">
            <MinusCircle className="inline-block h-3 w-3 mr-1" />
            {diff.text}
          </span>
        );
      case 1: // 添加
        return (
          <span className="bg-green-100 text-green-800 px-1 rounded">
            <PlusCircle className="inline-block h-3 w-3 mr-1" />
            {diff.text}
          </span>
        );
      default: // 相等
        return <span>{diff.text}</span>;
    }
  };
  
  // 并排视图
  const renderSplitView = () => {
    return (
      <div className="grid grid-cols-2 gap-4">
        <Card className="overflow-hidden">
          <div className="p-3 bg-muted/30 border-b">
            <h3 className="text-sm font-medium">{sourceTitle}</h3>
          </div>
          <ScrollArea className="h-[300px]">
            <pre className="p-4 text-xs whitespace-pre-wrap">
              {typeof sourceContent === 'string' 
                ? sourceContent 
                : JSON.stringify(sourceContent, null, 2)}
            </pre>
          </ScrollArea>
        </Card>
        
        <Card className="overflow-hidden">
          <div className="p-3 bg-muted/30 border-b">
            <h3 className="text-sm font-medium">{targetTitle}</h3>
          </div>
          <ScrollArea className="h-[300px]">
            <pre className="p-4 text-xs whitespace-pre-wrap">
              {typeof targetContent === 'string' 
                ? targetContent 
                : JSON.stringify(targetContent, null, 2)}
            </pre>
          </ScrollArea>
        </Card>
      </div>
    );
  };
  
  // 统一视图（内联差异）
  const renderUnifiedView = () => {
    return (
      <Card className="overflow-hidden">
        <div className="p-3 bg-muted/30 border-b">
          <h3 className="text-sm font-medium">差异视图</h3>
        </div>
        <ScrollArea className="h-[300px]">
          <pre className="p-4 text-xs whitespace-pre-wrap">
            {diffs.map((diff, index) => (
              <React.Fragment key={index}>
                {renderDiffItem(diff)}
              </React.Fragment>
            ))}
          </pre>
        </ScrollArea>
      </Card>
    );
  };
  
  // 加载中状态
  if (isLoading) {
    return (
      <div className="flex justify-center items-center p-8">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
      </div>
    );
  }
  
  return (
    <div className={`space-y-4 ${className}`}>
      <div className="flex justify-between items-center">
        <div className="flex items-center gap-2">
          <h3 className="text-base font-medium">文档比较</h3>
          {hasDifferences ? (
            <Badge variant="outline" className="bg-amber-100 text-amber-800 border-amber-200">
              <AlertCircle className="h-3 w-3 mr-1" />
              有差异 ({similarityPercentage}% 相似)
            </Badge>
          ) : (
            <Badge variant="outline" className="bg-green-100 text-green-800 border-green-200">
              <CheckCircle2 className="h-3 w-3 mr-1" />
              内容相同
            </Badge>
          )}
        </div>
        
        <div className="flex gap-2">
          {onSelectSource && (
            <Button variant="outline" size="sm" onClick={onSelectSource}>
              使用源文档
            </Button>
          )}
          
          {onMerge && hasDifferences && (
            <Button size="sm" onClick={() => onMerge(targetContent)}>
              <ArrowLeftRight className="h-4 w-4 mr-1" />
              智能合并
            </Button>
          )}
          
          {onSelectTarget && (
            <Button variant="outline" size="sm" onClick={onSelectTarget}>
              使用目标文档
            </Button>
          )}
        </div>
      </div>
      
      <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
        <TabsList className="grid w-full grid-cols-2">
          <TabsTrigger value="split">并排视图</TabsTrigger>
          <TabsTrigger value="unified">统一视图</TabsTrigger>
        </TabsList>
        
        <TabsContent value="split" className="pt-4">
          {renderSplitView()}
        </TabsContent>
        
        <TabsContent value="unified" className="pt-4">
          {renderUnifiedView()}
        </TabsContent>
      </Tabs>
    </div>
  );
} 